package com.maiji.cloud.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.plugin.Interceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Configuration
@ComponentScan(basePackages = {"com.gitee.sunchenbin.mybatis.actable.manager.*"})
public class JdbcConfig {

    @Value("${spring.datasource.driver-class-name}")
    private String driver;

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Bean
    public PropertiesFactoryBean configProperties() throws Exception{
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        propertiesFactoryBean.setLocations(resolver.getResources("classpath*:application.yml"));
        return propertiesFactoryBean;
    }

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DruidDataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    //配置Druid的监控
    //1、配置一个管理后台的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String,String> initParams = new HashMap<>();
        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","123456");
//        initParams.put("allow","");  //默认就是允许所有访问
//        initParams.put("deny","192.168.15.21");
        bean.setInitParameters(initParams);
        return bean;
    }
    //2、配置一个web监控的filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*");
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Arrays.asList("/*"));
        return  bean;
    }

        @Bean
        public DataSourceTransactionManager dataSourceTransactionManager() {
            DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
            dataSourceTransactionManager.setDataSource(dataSource());
            return dataSourceTransactionManager;
        }

        @Bean
        public MybatisSqlSessionFactoryBean sqlSessionFactory() throws Exception{
            MybatisSqlSessionFactoryBean mybatisPlusSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
            mybatisPlusSqlSessionFactoryBean.setDataSource(dataSource());
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources1 = resolver.getResources("classpath:com/maiji/cloud/mapper/*.xml");
            Resource[] resources2 = resolver.getResources("classpath*:com/gitee/sunchenbin/mybatis/actable/mapping/*/*.xml");
            int resources1Length = resources1.length;
            int resources2Length = resources2.length;
            resources1 = Arrays.copyOf(resources1, resources1Length+resources2Length);//数组扩容
            System.arraycopy(resources2, 0, resources1, resources1Length, resources2Length);
            mybatisPlusSqlSessionFactoryBean.setMapperLocations(resources1);
            mybatisPlusSqlSessionFactoryBean.setTypeAliasesPackage("com.maiji.cloud.entities.manager");
            // 执行分析插件，防止全表删除，开发使用
//            SqlExplainInterceptor sqlExplainInterceptor = new SqlExplainInterceptor();
//            sqlExplainInterceptor.setStopProceed(true);
            // 分页插件
            PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
            // sql性能分析插件
            PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
            performanceInterceptor.setFormat(false);  // 格式化sql
//            performanceInterceptor.setMaxTime(1000);  // 允许sql执行的最大毫秒数
            // 乐观锁插件
            OptimisticLockerInterceptor optimisticLockerInterceptor = new OptimisticLockerInterceptor();
            mybatisPlusSqlSessionFactoryBean.setPlugins(new Interceptor[]{paginationInterceptor, performanceInterceptor, optimisticLockerInterceptor});
            mybatisPlusSqlSessionFactoryBean.setGlobalConfig(globalConfiguration());
            return mybatisPlusSqlSessionFactoryBean;
        }

    /**
     * 逻辑删除插件
     */
    @Bean
    public GlobalConfiguration globalConfiguration() {
        GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector());
        conf.setLogicDeleteValue("1");
        conf.setLogicNotDeleteValue("0");
        conf.setIdType(3);
        return conf;
    }


}
